package com.umakr.ax.app.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Maps;
import com.umakr.ax.common.mapper.UserDetailsMapper;
import com.umakr.ax.common.model.UserDetails;
import com.umakr.ax.common.vo.VerifyUserInfoVO;
import com.umakr.ax.core.base.BaseService;
import com.umakr.ax.security.model.User;
import com.umakr.ax.security.service.UserService;
import com.umakr.ax.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


/**
 * <p>
 * 用户详情 服务实现类
 * </p>
 *
 * @author Umakr-Code-Generator
 * @since 2017-12-30
 */
@Service
public class AppUserDetailsService extends BaseService<UserDetailsMapper, UserDetails>{

    @Autowired
    UserService userService;

    @Autowired
    Environment env;

    private static final Integer VERIFY_CODE = 5;
    private static final String VO_NAME = "name";
    private static final String VO_CARDNUM = "num";
    private static final String OSS_IMG_PATH= "oss.img.path";
    private static final String USERID_KEY= "userId";
    private static final String UNICKNAME_KEY= "nickName";
    private static final String USERPHONE_KEY= "userPhone";
    private static final String ACATAR_KEY= "avatar";
    private static final String TOKEN_KEY= "token";
    private static final String BIRTHDAR_KEY= "birthday";

    private static final String USER_ID_KEY= "user_id";

    private static final String USERID_MSG= "用户id不能为空";

    public Object registerUser(String phone,String pwd,String nickName,Long userId) {
        String aliUrl = env.getProperty(OSS_IMG_PATH);
        int code = 0;
        String msg = "";

        Map<String,Object> remap = Maps.newHashMap();
        boolean userExit = userService.checkUsernameExit(phone);
        if(!userExit) {
            if (nickName == null || "".equals(nickName)) {
                if(userId == null){
                    msg = "用户id错误";
                }else{
                    EntityWrapper<UserDetails> udEn = new EntityWrapper<>();
                    udEn.eq(USER_ID_KEY,userId);
                    UserDetails ud = selectOne(udEn);
                    ud.setUserPhone(phone);
                    update(ud);

                    User u = userService.queryById(userId);
                    if(u == null) {
                        u = new User();
                    }
                    u.setAccount(phone);
                    u.setPassword(WebUtil.getBean(BCryptPasswordEncoder.class).encode(pwd));
                    u.setRemark("微信用户注册");
                    u.setStatus(1);
                    userService.update(u);

                    remap.put(USERID_KEY,ud.getUserId());
                    remap.put(UNICKNAME_KEY,ud.getNickname()==null?"":ud.getNickname());
                    remap.put(USERPHONE_KEY,ud.getUserPhone()==null?"":ud.getUserPhone());
                    remap.put(ACATAR_KEY,FormatPhotoUrlUtil.formatString(aliUrl,ud.getHeadimgurl()));
                    remap.put(TOKEN_KEY,userService.login(phone,pwd));
                    remap.put("sex", ud.getSex() == null ? 1 : ud.getSex());
                    remap.put(BIRTHDAR_KEY, ud.getBirthday() == null ? "" : ud.getBirthday());
                    code = 1;
                }
            } else {
                Object obj = userService.registerUser(phone,pwd);
                if(obj instanceof User){
                    msg = "注册成功";
                    UserDetails ud = new UserDetails();
                    ud.setUserId(((User) obj).getId());
                    ud.setCreateTime(new Date());
                    ud.setUserPhone(phone);
                    ud.setNickname(nickName);
                    ud = update(ud);
                    remap.put(USERID_KEY,ud.getUserId());
                    remap.put(UNICKNAME_KEY,ud.getNickname()==null?"":ud.getNickname());
                    remap.put(USERPHONE_KEY,ud.getUserPhone()==null?"":ud.getUserPhone());
                    remap.put(ACATAR_KEY, FormatPhotoUrlUtil.formatString(aliUrl,ud.getHeadimgurl()));
                    remap.put("sex", ud.getSex() == null ? 1 : ud.getSex());
                    remap.put(BIRTHDAR_KEY, ud.getBirthday() == null ? "" : ud.getBirthday());
                    remap.put(TOKEN_KEY,userService.login(phone,pwd));
                    code = 1;
                }else{
                    return obj;
                }
            }
        }else{
            msg = "该手机号已被注册";
        }

        return resultMap(remap,code,msg);
    }

    public Object modifyPwd(String account,String oldPwd, String newPwd, String confirmPwd,boolean isForeget ) {
        EntityWrapper<User> userEntityWrapper = new EntityWrapper<>();
        userEntityWrapper.eq("account",account);
        User user = userService.selectOne(userEntityWrapper);
        if(user == null){
            Map<String,Object> resultMap = Maps.newLinkedHashMap();
            resultMap.put("errorCode",0);
            resultMap.put("msg","该手机号尚未注册");
            return resultMap;
        }
        if(isForeget){
            return userService.changePwd(account,newPwd,confirmPwd);
        }else {
            return userService.modifyPwd(account, oldPwd, newPwd, confirmPwd);
        }
    }

    public Map<String, Object> updateUserInfo(Long userId,String params) {
        String aliUrl = env.getProperty(OSS_IMG_PATH);
        int code = 1;
        String msg = "修改成功";

        EntityWrapper<UserDetails> entityWrapper = new EntityWrapper<>();
        entityWrapper.eq(USER_ID_KEY,userId);
        UserDetails ud = selectOne(entityWrapper);

        if(ud == null){
            ud = new UserDetails();
        }
        JSONObject jo = JSONObject.parseObject(params);

        Iterator<String> it = jo.keySet().iterator();
        while(it.hasNext()){
            String key = it.next().replace("\"","");
            Object value = jo.get(key);

            try {
                String pName = ud.getClass().getDeclaredField(key).getName();
                pName = pName.substring(0,1).toUpperCase()+pName.substring(1);
                Class zclass = ud.getClass().getMethod("get"+pName).getReturnType();
                Method m = ud.getClass().getMethod("set"+pName,zclass);
                m.invoke(ud,zclass.cast(value));
            } catch (Exception e) {
                code = 0;
                msg = "修改失败";
                break;
            }

        }

        if(code == 0){
            return resultMap(code,msg);
        }else {
            baseMapper.update(ud);
            Map<String, Object> remap = Maps.newHashMap();
            remap.put(USERID_KEY, ud.getId());
            remap.put(UNICKNAME_KEY, ud.getNickname() == null ? "" : ud.getNickname());
            remap.put(USERPHONE_KEY, ud.getUserPhone() == null ? "" : ud.getUserPhone());
            remap.put(ACATAR_KEY, FormatPhotoUrlUtil.formatString(aliUrl,ud.getHeadimgurl()));
            return resultMap(remap);
        }
    }

    public Map<String, Object> realNameVerified( VerifyUserInfoVO vo) {
        int code = 0;
        String msg = "";
        String localBaseUploadDir = env.getProperty("local.file.upload");
        if(vo.getUserId() != null) {
            try {
                EntityWrapper<UserDetails> userEntity = new EntityWrapper<>();
                userEntity.eq("user_card",vo.getCardNum());
                List<UserDetails> userList = selectList(userEntity);
                if(userList.isEmpty()) {
                    userEntity = new EntityWrapper<>();
                    userEntity.eq(USER_ID_KEY,vo.getUserId());
                    UserDetails userDetails = selectOne(userEntity);
                    if (userDetails != null) {

                        String verifyKey = "verify.times."+vo.getUserId();
                        Integer verifyCode = 0;
                        if (CacheUtil.getCache().exists(verifyKey)) {
                            verifyCode = Integer.parseInt(CacheUtil.getCache().getKeyValue(verifyKey).toString());
                        }
                        if(verifyCode < VERIFY_CODE) {
                            verifyCode++;
                            CacheUtil.getCache().setKeyValue(verifyKey, verifyCode);

                            Object verifiyResult = IDCardUtil.aliIDCardDistinguish(localBaseUploadDir + vo.getCardForward());
                            if (verifiyResult instanceof JSONObject) {
                                JSONObject jov = (JSONObject) verifiyResult;
                                if (jov.get(VO_NAME).equals(vo.getName()) && jov.get(VO_CARDNUM).equals(vo.getCardNum())) {
                                    userDetails.setRealname(vo.getName());
                                    userDetails.setUserCard(vo.getCardNum());

                                    JSONObject jo = new JSONObject();
                                    jo.put("card1", vo.getCardForward());
                                    jo.put("card2", vo.getCardBack());
                                    userDetails.setExtraInfo(jo.toJSONString());

                                    userDetails.setUserAuditStatus(1);
                                    userDetails.setUpdateTime(new Date());
                                    code = 1;
                                    msg = "审核成功";
                                } else {
                                    msg = "认证失败，认证信息与身份证照片的信息不符";
                                    userDetails.setUserAuditStatus(0);
                                }
                            } else {
                                msg = "认证失败，请上传真实有效的身份证照片";
                                userDetails.setUserAuditStatus(0);
                            }
                            baseMapper.update(userDetails);
                        } else {
                            msg = "您已超过今日认证次数";
                        }

                    }else {
                        msg = "用户不存在";
                    }
                } else {
                    msg = "该身份证号已被注册";
                }
            } catch (RuntimeException  e) {
                msg = e.getMessage();
            }
        }else{
            msg = USERID_MSG;
        }

        return resultMap(code,msg);
    }

    public Map<String, Object> getRealNameVerifyInfo(Long userId){
        int code = 0;
        String msg = "";
        String verifyUrl = env.getProperty("verify.resource.path");
        VerifyUserInfoVO vo = new VerifyUserInfoVO();
        if(userId != null) {
            EntityWrapper<UserDetails> userEntity = new EntityWrapper<>();
            userEntity.eq(USER_ID_KEY,userId);
            UserDetails ud = selectOne(userEntity);
            if (ud != null) {
                if(ud.getUserAuditStatus() != null) {
                    vo.setUserId(ud.getUserId());
                    vo.setName(ud.getRealname());
                    vo.setCardNum(ud.getUserCard());
                    vo.setPhone(ud.getUserPhone());
                    Integer status = ud.getUserAuditStatus()==null?3:ud.getUserAuditStatus();
                    vo.setVerifyStatus(ud.getUserAuditStatus());
                    String vName = "";
                    switch (status){
                        case 0:vName = "审核失败";break;
                        case 1:vName = "审核成功";break;
                        case 2:vName = "待审核";break;
                        case 3:vName = "未认证";break;
                        default:
                            vName = "未认证";break;
                    }
                    vo.setVerifyStatusName(vName);
                    JSONObject jo = JSONObject.parseObject(ud.getExtraInfo());
                    vo.setCardForward(jo == null?"":FormatPhotoUrlUtil.formatString(verifyUrl,jo.get("card1")));
                    vo.setCardBack(jo == null?"":FormatPhotoUrlUtil.formatString(verifyUrl,jo.get("card2")));
                    code = 1;
                }else{
                    code = 2;
                    msg = "您还未进行实名认证，请尽快进行实名认证";
                }

            } else {
                msg = USERID_MSG;
            }
        }else{
            msg = USERID_MSG;
        }

        if(code == 1) {
            return resultMap(vo, code, msg);
        }else{
            return resultMap(code, msg);
        }
    }

    public Object wxRegister( Long userId,String nickName,String openId,String headImgUrl,
                             Integer sex,String country,String city,String province,String unionid){
        String aliUrl = env.getProperty(OSS_IMG_PATH);
        int code = 1;
        String msg = "";

        int exitFlag = 0;
        Map<String,Object> result = Maps.newHashMap();
        if(unionid == null || "".equals(unionid)) {
            code = 0;
            msg = "绑定错误";
            exitFlag = -1;
        }else {
            EntityWrapper<UserDetails> udEn = new EntityWrapper<>();
            udEn.eq("unionid", unionid);
            UserDetails ud = selectOne(udEn);
            if (ud == null) {
                if (userId != null) {
                    EntityWrapper<UserDetails> udUserEn = new EntityWrapper<>();
                    udUserEn.eq(USER_ID_KEY, userId);
                    ud = selectOne(udUserEn);
                    ud.setUserId(userId);

                } else {
                    ud = new UserDetails();
                    User user = new User();
                    user.setRemark("微信登陆，尚未注册手机号");
                    user = userService.update(user);
                    userId = user.getId();
                    ud.setUserId(userId);

                }

                ud.setNickname(nickName);
                ud.setOpenid(openId);
                ud.setHeadimgurl(headImgUrl);
                ud.setSex(sex);
                ud.setCountry(country);
                ud.setCity(city);
                ud.setProvince(province);
                ud.setUnionid(unionid);

                ud = update(ud);
            } else {
                if (!ud.getUserId().equals(userId)&&userId != null) {
                        code = 1;
                        msg = "此微信号已被注册";
                }
            }

            if(ud.getUserPhone() == null){
                exitFlag = 1;
            }else{
                exitFlag = 0;
            }

            result.put(TOKEN_KEY, userService.weXinLoginToken(ud.getUserId()));
            result.put(USERID_KEY, ud.getUserId());
            result.put("sex", ud.getSex() == null ? 1 : ud.getSex());
            result.put(BIRTHDAR_KEY, ud.getBirthday() == null ? "" : ud.getBirthday());
            result.put(ACATAR_KEY, FormatPhotoUrlUtil.formatString(aliUrl,ud.getHeadimgurl()));
            result.put(UNICKNAME_KEY, ud.getNickname() == null ? "" : ud.getNickname());
            result.put("phone", ud.getUserPhone() == null ? "" : ud.getUserPhone());
        }
        result.put("status", exitFlag);

        return resultMap(result,code,msg);
    }

    public Object fileUpload(Long userId, MultipartFile file){
        String localBaseUploadDir = env.getProperty("local.file.upload");
        Map<String,Object> result = Maps.newHashMap();
        String filePath = FileUploadUtil.fileUpload(file,localBaseUploadDir  + File.separator+ "idcard" + File.separator+userId);
        result.put("filePath", filePath.replace(localBaseUploadDir,""));
        if(filePath.startsWith(localBaseUploadDir)){
            return resultMap(result,1,"上传成功");
        }else{
            return resultMap(0,filePath);
        }
    }
}
